package com.iwhalecloud.bss.kite.cucc.service.util;

import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.jcraft.jsch.*;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.net.URLDecoder;
import java.util.Properties;

/**
 * Description:
 * File Name:FtpUtils
 * Modification History:
 * Date             Author      Version     Description
 * ------------------------------------------------------------------
 * 2021-4-21 17:14   邱萌         1.0       1.0 Version
 **/
public class FtpUtils {
    public static final int DEFAULT_TIMEOUT_IN_MILLS = 90000;
    private final ZLogger logger = ZLoggerFactory.getLogger(this.getClass(), KeyConsts.LOG_MODULE);
    private FTPClient ftp;
    private static Session sshSession;
    private static ChannelSftp sftp;

    public void closeServer() throws IOException {
        if (ftp.isConnected()) {
            ftp.disconnect();
        }
    }

    /**
     * 获取ftp连接
     *
     * @param f
     * @return
     * @throws Exception
     */
    public boolean connectFtp(FtpConfig f) throws Exception {
        ftp = new FTPClient();
        ftp.setDefaultTimeout(DEFAULT_TIMEOUT_IN_MILLS);
        boolean flag = false;
        int reply;
        if (f.getPort() == null) {
            ftp.connect(f.getAddr(), 21);
        } else {
            ftp.connect(f.getAddr(), Integer.valueOf(f.getPort()));
        }
        ftp.login(f.getUsername(), f.getPassword());
        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
        reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
            return flag;
        }
        ftp.setDataTimeout(60000);
        ftp.setSoTimeout(DEFAULT_TIMEOUT_IN_MILLS);
        ftp.changeWorkingDirectory(f.getRoot());
        flag = true;
        return flag;
    }

    /**
     * 关闭ftp连接
     */
    public void closeFtp() {
        if (ftp != null && ftp.isConnected()) {
            try {
                ftp.logout();
                ftp.disconnect();
            } catch (IOException e) {
                logger.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, "closeFtp：" + e.getMessage());
            }
        }
    }

    public boolean download(String remoteFileName, String localFileName)
        throws IOException {
        boolean flag = false;
        localFileName = URLDecoder.decode(localFileName, "utf-8");
        File outfile = new File(localFileName);
        OutputStream oStream = null;
        try {
            oStream = new FileOutputStream(outfile);
            flag = ftp.retrieveFile(new String(remoteFileName.getBytes("GBK"), "iso-8859-1"), oStream);
        } catch (IOException e) {
            flag = false;
            return flag;
        } finally {
            if (null != oStream) {
                oStream.close();
            }
        }
        return flag;
    }
    /**
     * 从ftp上获取文件流然后转换为字节数组
     * @param remoteFileName
     * @return
     */
    public byte[] getBytes(String remoteFileName) throws IOException {
            InputStream inputStream = ftp.retrieveFileStream(remoteFileName);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
    }

    /**
     * 连接sftp服务器
     * @param f
     * @return
     * @throws Exception
     */
    public static boolean sftpConnection (FtpConfig f) throws Exception{
        JSch jsch = new JSch();
        String host = f.getAddr();
        int port =  Integer.parseInt(f.getPort());
        String userName = f.getUsername();
        String password = f.getPassword();
        jsch.getSession(userName, host, port);
        sshSession = jsch.getSession(userName, host, port);
        sshSession.setPassword(password);
        Properties properties = new Properties();
        properties.put("StrictHostKeyChecking", "no");
        sshSession.setConfig(properties);
        sshSession.connect();
        Channel channel = sshSession.openChannel("sftp");
        channel.connect();
        sftp = (ChannelSftp) channel;
        return true;
    }

    /**
     * 从sftp上获取文件流然后转换为字节数组
     * @param remoteFileName
     * @return
     */
    public byte[] getSftpBytes(String remoteFileName){
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            InputStream inputStream = sftp.get(remoteFileName);
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
        } catch (Exception e) {
//            e.printStackTrace();
        }
        return output.toByteArray();
    }

    /**
     *@description 退出Sftp服务器登录
     *@return
     **/
    public void sftpClose(){
        if (sftp != null) {
            if (sftp.isConnected()){
                sftp.disconnect();
            }
        }
    }

    /**
     * 关闭session
     */
    public static void sessionClose(){
        if (sshSession != null) {
            if (sshSession.isConnected()){
                sshSession.disconnect();
                sshSession = null;
            }
        }
    }
}
